﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Caching;
using System.Data;
using System.Data.SqlClient;
using System.Net;

namespace TBM.Filters
{
    public class TBMAuthorizeAttribute : AuthorizeAttribute 
    {
        private string ControllerDescr;
        private string ActionDescr;

        public TBMAuthorizeAttribute(string controllerDescr, string actionDescr)
        {
            ControllerDescr = controllerDescr;
            ActionDescr = actionDescr;      
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool result = false;

            if (httpContext == null)
            {
                throw new ArgumentNullException("权限过滤未能获取到正确的参");
            }

            // 处理权限
            List<TBM.Models.Permission> permissions = null;

            if (HttpRuntime.Cache.Get("Permission") != null)
            {
                permissions = (List<TBM.Models.Permission>)HttpRuntime.Cache.Get("Permission");
            }
            else
            {
                permissions = new List<Models.Permission>();

                SqlCommand cmd = new SqlCommand();
                cmd.Connection = new SqlConnection(Core.Config.ConnectionString);
                cmd.Connection.Open();
                cmd.CommandText = "p_ModulePermissions";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("@UID", SqlDbType.VarChar, 15);
                cmd.Parameters["@UID"].Value = HttpContext.Current.User.Identity.Name;

                try
                {
                    SqlDataReader dr = cmd.ExecuteReader();

                    while (dr.Read())
                    {
                        permissions.Add(new Models.Permission
                        {
                            ID = (int)dr["ID"],
                            ControllerDescr = dr["ControllerDescr"].ToString(),
                            ActionDescr = dr["ActionDescr"].ToString()
                        });
                    }
                }
                catch
                {
                    cmd.Connection.Close();
                    HttpContext.Current.Response.Redirect("~/error/code500");
                }

                cmd.Connection.Close();

                HttpRuntime.Cache.Insert("Permission", permissions, null, DateTime.UtcNow.AddMinutes(20), Cache.NoSlidingExpiration);
            }

            result = permissions.Where(p => p.ControllerDescr == ControllerDescr && p.ActionDescr == ActionDescr).Count() > 0;

            if (!result)
            {
                httpContext.Response.StatusCode = 203;
            }

            return result;
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            HttpContextBase context = filterContext.HttpContext;
            bool ajaxRequest = false;
            if (context.Request["ajax"] != null)
            {
                bool.TryParse(context.Request["ajax"].ToString(), out ajaxRequest);
            }

            if (!ajaxRequest)
            {
                switch (context.Response.StatusCode)
                {
                    case 203:
                        {
                            // 非授权信息
                            context.Response.Redirect("~/error/code203");
                            break;
                        }
                    case 404:
                        {
                            // 未找到页面
                            context.Response.Redirect("~/error/code404");
                            break;
                        }
                }
            }
            else
            {
                if (context.Response.StatusCode != 200)
                {
                    context.Response.Clear();
                    context.Response.ContentType = "application/json";

                    switch (context.Response.StatusCode)
                    {
                        case 203:
                            {
                                // 非授权信息
                                context.Response.Write(ResponseStatusJson(203, "您无权进行此项操作"));
                                break;
                            }
                        case 404:
                            {
                                // 未找到页面
                                context.Response.Write(ResponseStatusJson(404, "未找到页面"));
                                break;
                            }
                        case 500:
                            {
                                // 程序执行错误
                                context.Response.Write(ResponseStatusJson(500, "程序执行错误"));
                                break;
                            }
                    }

                    context.Response.End();
                }
            }
        }

        private string ResponseStatusJson(int httpCode, string message)
        {
            return "{" + String.Format("\"Result\": false, \"Status\": {0}, \"Message\": \"{1}\"", httpCode, message) + "}";
        }
    }
}